package com.normalsys.live.service;

import com.alibaba.fastjson.JSONObject;
import com.normalsys.live.base.annotation.DistributedLockAble;
import com.normalsys.live.base.config.Constant;
import com.normalsys.live.base.config.ResponseCode;
import com.normalsys.live.base.exp.BizException;
import com.normalsys.live.base.util.SmsUtil;
import com.normalsys.live.base.util.bean.BeanUtil;
import com.normalsys.live.base.util.string.ObjectTranslate;
import com.normalsys.live.base.util.string.StringUtil;
import com.normalsys.live.base.util.token.AesUtil;
import com.normalsys.live.base.util.token.DateUtil;
import com.normalsys.live.base.util.token.TokenUtil;
import com.normalsys.live.bean.LoginParamBean;
import com.normalsys.live.dao.*;
import com.normalsys.live.entity.*;
import com.normalsys.live.vo.LoginVO;
import com.normalsys.live.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: 刘天宇
 * Date: 2018/7/16
 * Time: 21:21
 * Description:
 */
@Service
@Slf4j
public class LoginService {

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private SmsCodeDAO smsCodeDAO;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 微信登录
     * @param openid
     * @param map
     * @return
     */
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_COMMITTED)
    @DistributedLockAble(prefix = "SHOES_WECHAT_SIGN")
    public LoginVO wechatSign(String openid, Map<String, Object> map) {
        Boolean isNewUser = false;
        //放入缓存--redis
        Map<String,Object> sessionKeys = redisTemplate.opsForHash().entries("live_sessionKeys");
        if(StringUtil.isEmpty(sessionKeys)) {
            sessionKeys = new HashMap<>();
        }
        sessionKeys.put(openid, map);
        redisTemplate.opsForHash().putAll("live_sessionKeys", sessionKeys);

        //查询该用户是否存在
        User param = new User();
        param.setOpenid(openid);
        User user = userDAO.selectOne(param);
        LoginVO loginVO = new LoginVO();

        if(null == user) {
            //不存在 添加
            param.setBirth(Constant.USER_BIRTH);
            param.setGender(Constant.USER_GENDER);
            param.setImg(Constant.USER_IMG);
            param.setNickName(Constant.USER_NAME);
            param.setCreateTime(DateUtil.getNowStringDate());
            param.setPhone("");
            param.setUnionId("");
            param.setProvinceId("");
            param.setCityId("");
            param.setAreaId("");
            param.setArea("");
            param.setAge(0);
            param.setLastLoginTime(DateUtil.getNowStringDate());
            userDAO.insert(param);
            user = param;
            isNewUser = true;
        }
        String token = TokenUtil.createToken(user.getId() + "");

        UserVO userVO = BeanUtil.copy(user, UserVO.class);
        loginVO.setIsBind(!StringUtil.isEmpty(user.getPhone()));
        loginVO.setUserVO(userVO);
        loginVO.setToken(token);
        loginVO.setIsNewUser(isNewUser);
        return loginVO;
    }

    /**
     * 获得用户信息
     * @param encryptedData
     * @param iv
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_COMMITTED)
    public LoginVO getUserInfo(String encryptedData, String iv, String userId) {
        //构造返回信息
        LoginVO loginVO = new LoginVO();
        Long id = Long.valueOf(userId);
        //查询用户信息
        User param = new User();
        param.setId(id);
        User user = userDAO.selectOne(param);

        if(null == user) {
            throw new BizException(ResponseCode.PARAM_ILLEGAL_ERROR, "用户不存在");
        }
        userDAO.updateByPrimaryKeySelective(user);
        if(!Constant.USER_IMG.equals(user.getImg())) {//头像不等于默认，就修改过了，不允许获得了
            loginVO.setUserVO(BeanUtil.copy(user, UserVO.class));
            loginVO.setIsBind(!StringUtil.isEmpty(user.getPhone()));
            return loginVO;
        }

        String openid = user.getOpenid();
        //缓存--redis
        Map<String,Object> sessionKeys = redisTemplate.opsForHash().entries("shoes_sessionKeys");
        if(StringUtil.isEmpty(sessionKeys)) {
            sessionKeys = new HashMap<>();
        }
        String sessionKey = ObjectTranslate.getString(((Map<String, Object>) sessionKeys.get(openid)).get("session_key"));

        try {
            String result = AesUtil.decrypt(encryptedData, sessionKey, iv, "UTF-8");
            log.info("result =====================>"+result);
            if (null != result && result.length() > 0) {
                Map<String,Object> map = JSONObject.parseObject(result);
                user.setNickName(ObjectTranslate.getString(map.get("nickName")));
                user.setImg(ObjectTranslate.getString(map.get("avatarUrl")));
                user.setUnionId(map.containsKey("union_id")?ObjectTranslate.getString(map.get("union_id")):"");

                userDAO.updateByPrimaryKeySelective(user);
                loginVO.setUserVO(BeanUtil.copy(user, UserVO.class));
                loginVO.setIsBind(!StringUtil.isEmpty(user.getPhone()));
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        //更新用户信息
        return loginVO;
    }

    /**
     * 发送验证码
     * @return
     */
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_COMMITTED)
    @DistributedLockAble(prefix = "SEND_CODE")
    public void sendCode(String phone) {

        //查询手机号1分钟前是否发送过
        SmsCode currentSmsCode = smsCodeDAO.getCodeByPhoneOneMinute(phone, DateUtil.longToStrDate(System.currentTimeMillis() - 6000));
        if(null != currentSmsCode) {
            throw new BizException(ResponseCode.PARAM_ILLEGAL_ERROR, "请勿重复发送验证码");
        }

        String code = Math.round(Math.random() * 100000 + 99999) + "";
//        String code = "123456";
        //发送验证码
        boolean flag = SmsUtil.send(phone, code);
        if(!flag) {
            throw new BizException(ResponseCode.PARAM_ILLEGAL_ERROR, "验证码发送失败");
        }
        SmsCode smsCode = new SmsCode();
        smsCode.setPhone(phone);
        smsCode.setCode(code);
        smsCode.setStatus(1);
        smsCode.setCreateTime(DateUtil.getNowStringDate());

        smsCodeDAO.insert(smsCode);
    }

}
